package com.vinjogames.ui;

import javax.microedition.khronos.opengles.GL10;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.text.InputFilter;
import android.text.InputType;
import android.widget.EditText;

import com.vinjogames.TankGame.R;
import com.vinjogames.TankGame.TankGameActivity;
import com.vinjogames.entities.Game;
import com.vinjogames.gfx.Camera;
import com.vinjogames.gfx.GameView;
import com.vinjogames.gfx.Image;
import com.vinjogames.gfx.LoadingScreen;
import com.vinjogames.network.ConnectionManager;
import com.vinjogames.network.Server;
import com.vinjogames.util.GameConVars;
import com.vinjogames.util.InputManager;
import com.vinjogames.util.Logger;
import com.vinjogames.util.Preferences;

public class TitleMenu {

	private Game mGame;
	private GameView mView;
	private Context mContext;
	private ConnectionManager mConnectionManager;
	private MapMenu mMapMenu;
	
	//Menu
	private Image mBackground;
	private Image mWindowBorder;
	private PointF mBackLocation;
	private PressableButton mLocalGame;
	private PressableButton mNetworkGame;
	private PressableButton mOptions;
	private PressableButton mQuit;
	//Options
	private boolean mInOptions;
	private boolean mInMapMenu;
	private PressableButton mOptionsOK;
	private PressableButton mMusic;
	private PressableButton mSound;
	private PressableButton mVibrate;
	private PressableButton mDebug;
	private AlertDialog mConnectDialog;
	
	//TODO:  make a menu system
	//pass in list of variables, name: value, show in buttons
	//May need scroll or pagination
	//

	public TitleMenu(){
		mConnectionManager = ConnectionManager.getInstance();
		mInOptions = false;
		mBackLocation = new PointF(Camera.GL_WIDTH/2,Camera.GL_HEIGHT/2);
	}
	
	public void init(TankGameActivity act){
		mGame = act.getGame();
		mView = act.getView();
		mContext = act;
		mMapMenu = new MapMenu(mGame);
	}

	public void load(){
		mBackground  = new Image(GameConVars.MENUBACKGROUND, Camera.GL_WIDTH, Camera.GL_HEIGHT);
		mWindowBorder= new Image(GameConVars.GRAPHIC_WINDOW_BORDER, Camera.GL_WIDTH, Camera.GL_HEIGHT);
		mLocalGame   = new PressableButton("Local Game", new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 2f), 
				       new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 1f));
		mNetworkGame = new PressableButton("Network Game", new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 3f),
				       new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 2f));
		mOptions     = new PressableButton("Options", new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 4f),
				       new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 3f));
		mQuit        = new PressableButton("Quit", new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 5f),
				       new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 4f));

		//TODO: Magic numbers
		mOptionsOK = new PressableButton("Ok", new PointF(4.5f,0), new PointF(5.5f,1));
		mMusic     = new PressableButton("Music: " + Preferences.getMusicSetting(), new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 2f), 
				     new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 1f));
		mSound     = new PressableButton("Sound: " + Preferences.getSoundSetting(), new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 3f),
				     new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 2f));
		mVibrate   = new PressableButton("Vibrate: " + Preferences.getVibrateSetting(), new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 4f),
				     new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 3f));
		mDebug     = new PressableButton("Debug: " + Preferences.isDebug(), new PointF((Camera.GL_WIDTH/2) - 2f, Camera.GL_HEIGHT - 5f),
				     new PointF((Camera.GL_WIDTH/2) + 2f, Camera.GL_HEIGHT - 4f));
		
		mMapMenu.load();
	}

	public void draw(GL10 gl){
		gl.glPushMatrix();
		gl.glTranslatef(-Camera.GL_WIDTH/2, -Camera.GL_HEIGHT/2, Camera.Z_DISTANCE); //Move Everything down left/down
		if(mInOptions){
			optionsDraw(gl);
			return;
		}
		if(mInMapMenu){
			mMapMenu.draw(gl);
		}
		else{
			menuDraw(gl);
		}
		gl.glPopMatrix();
	}

	private void optionsDraw(GL10 gl){
		mBackground.draw(gl, mBackLocation);
		mMusic.draw(gl);
		mSound.draw(gl);
		mVibrate.draw(gl);
		mOptionsOK.draw(gl);
		mDebug.draw(gl);
	}

	private void menuDraw(GL10 gl){
		mBackground.draw(gl, mBackLocation);
		mWindowBorder.draw(gl, mBackLocation);
		mLocalGame.draw(gl);
		mNetworkGame.draw(gl);
		mOptions.draw(gl);
		mQuit.draw(gl);
	}

	public void handleTouch(PointF glLocation) throws Exception{
		if(mInOptions){
			if(mOptionsOK.insideBox(glLocation)){
				mInOptions = false;
			}
			if(mMusic.insideBox(glLocation)){
				Preferences.ToggleMusic();
				mMusic.setText("Music: " + Preferences.getMusicSetting());
			}
			if(mSound.insideBox(glLocation)){
				Preferences.ToggleSound();
				mSound.setText("Sound: " + Preferences.getSoundSetting());

			}
			if(mVibrate.insideBox(glLocation)){
				Preferences.ToggleVibrate();
				mVibrate.setText("Vibrate: " + Preferences.getVibrateSetting());
			}
			if(mDebug.insideBox(glLocation)){
				Preferences.ToggleDebug();
				mDebug.setText("Debug: " + Preferences.isDebug());
			}
			
		}else if(mInMapMenu){
			mMapMenu.handleTouch(glLocation);
		}else{
			if(mLocalGame.insideBox(glLocation)){
				
				newLocalGame();
			}
			if(mNetworkGame.insideBox(glLocation)){
				newOnlineGame();
			}
			if(mOptions.insideBox(glLocation)){
				showOptions();
			}
			if(mQuit.insideBox(glLocation)){
				InputManager.getInstance().quit();
			}
		}

	}

	private void showConnectDialog(String serverIP){
		//server sync stuck forever on bad wifi
		final EditText input = new EditText(mContext);
		input.setText(Preferences.getLastIP());
		input.setFilters((new InputFilter[]{new InputFilter.LengthFilter(15)}));//15=Max ipv4 + dots
		input.setInputType(InputType.TYPE_CLASS_PHONE);//closest to ip, numbers and periods
		input.setSingleLine();
		mConnectDialog = new AlertDialog.Builder(mContext).create();
		mConnectDialog.setView(input);
		mConnectDialog.setTitle(mContext.getString(R.string.connect));
		mConnectDialog.setMessage(mContext.getString(R.string.serverstart) + serverIP + "\n" +
				mContext.getString(R.string.enterip));
		mConnectDialog.setButton(AlertDialog.BUTTON_POSITIVE,mContext.getString(R.string.connectbtn), new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				final String ip = input.getText().toString().trim();
				//TODO:  verify its an ip
				final ProgressDialog pDialog = ProgressDialog.show(mContext, "", "Connecting to: " + ip, true);
				new Thread() {
					public void run() {
						try{
							boolean success = mConnectionManager.connect(ip, Server.SERVER_PORT);
							Preferences.setLastIP(ip);
							Message msg = Message.obtain();
							msg.arg2 = success ? 1 : -1;
							handler.sendMessage(msg);
						} catch (Exception e) {

						}
						pDialog.dismiss();                                   
					}
				}.start();
			}
		});
		
		mConnectDialog.setButton(AlertDialog.BUTTON_NEGATIVE,mContext.getString(R.string.cancelbtn), new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				//stop server??
			}
		});
		
		mConnectDialog.show();
	}

	private void showOptions(){
		mInOptions = true;
	}

	private void newLocalGame(){
		LoadingScreen.getInstance().show();
		mView.loadAllResources();
		mInMapMenu = true;
	}

	private void newOnlineGame(){
		final ProgressDialog dialog = ProgressDialog.show(mContext, "", "Starting Server", true);
		new Thread() {
			public void run() {
				try{
					String ip = mConnectionManager.startServer();
					Message msg = Message.obtain();
					msg.arg1 = ip != null ? 1 : -1;
					handler.sendMessage(msg);
				} catch (Exception e) {
					Logger.e(e);
				}
				dialog.dismiss();                                   
			}
		}.start();
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if(msg.arg1 == 1){//success
				showConnectDialog(Server.SERVER_IP);
			}
			if (msg.arg1 == -1){//failure
				Logger.popUp("Failed to start server");
			}
			if(msg.arg2 == -1){//failure
				Logger.popUp("Failed to connect to: " + mConnectionManager.getClient().getServerIP());
			}
			
			if(msg.arg2 == 1){ //success  1st player
				if(mConnectDialog.isShowing()) { mConnectDialog.cancel(); }
				try {
					mGame.start(GameConVars.GAME_NETWORK,true, 0);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}//TODO:  pass selected map
			}
			
			if(msg.arg2 == 2){ //success 2nd player
				if(mConnectDialog.isShowing()) { mConnectDialog.cancel(); }
				try {
					mGame.start(GameConVars.GAME_NETWORK,false,0);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}//TODO:  pass selected map
			}

		}
	};
	
	public Handler getHandler(){ return handler; }
}
